#include "..\base\ASStdLib.h"
#include "ASImage.h"
#ifdef AS_USE_IMAGE_RESOURCE_MANAGER
#include "ASImageMgr.h"
#endif

static as_ret as_ctrl_image_load_data_from_res(as_image* image_p, ASINT if_auto_resize)
{
    as_ret ret = AS_OK;
    ASINT res_hdlr;
#ifdef AS_USE_IMAGE_RESOURCE_MANAGER
    as_image_resmgr*  img_resmgr_p = as_image_resmgr_get_instance();
#else
    ASINT data_length;
#endif

    if(!image_p)
    {
        return AS_INVALID_PARAM;
    }

#ifdef AS_USE_IMAGE_RESOURCE_MANAGER
    res_hdlr = img_resmgr_p->add(img_resmgr_p, image_p->src_type, image_p->path, &image_p->res_info);

    if(res_hdlr < 0)
    {
        return AS_INTERNAL_ERROR;
    }

#else//AS_USE_IMAGE_RESOURCE_MANAGER
    res_hdlr = as_load_res_internal(as_ascii_from_ucs2(image_p->path), &image_p->res_info);

    if(res_hdlr < 0)
        return AS_INTERNAL_ERROR;

#endif//AS_USE_IMAGE_RESOURCE_MANAGER
    //get width and height of the image
    image_p->img_w = image_p->res_info.res_w;
    image_p->img_h = image_p->res_info.res_h;
    return ret;
}

static as_ret as_ctrl_image_load_data_from_file(as_image* image_p, ASINT if_auto_resize)
{
    as_ret ret = AS_OK;
    //    ASUINT8* res_data = NULL;
    //    struct frame_prop* prop_p = NULL;
    //#ifdef AS_USE_IMAGE_RESOURCE_MANAGER
    //    as_image_resmgr*  img_resmgr_p = as_image_resmgr_get_instance();
    //#else
    //    ASINT data_length;
    //    ASINT fh = -1;
    //    ASUINT len;
    //#endif
    //
    //    if(!image_p)
    //    {
    //        ret = AS_INVALID_PARAM;
    //        return ret;
    //    }
    //
    //#ifdef AS_USE_IMAGE_RESOURCE_MANAGER
    //    image_p->canvas_hdlr = img_resmgr_p->add(img_resmgr_p, image_p->src_type, image_p->path);
    //
    //    if(image_p->canvas_hdlr < 0)
    //    {
    //        return AS_INTERNAL_ERROR;
    //    }
    //
    //#else//AS_USE_IMAGE_RESOURCE_MANAGER
    //    fh = vm_file_open(image_p->path, MODE_READ, TRUE);
    //
    //    if(fh <= VM_FILE_OK)
    //    {
    //        ret = AS_INVALID_PARAM;
    //        return ret;
    //    }
    //
    //    if(vm_file_getfilesize(fh, (ASUINT*)&data_length) != 0)
    //    {
    //        vm_file_close(fh);
    //        ret = AS_INTERNAL_ERROR;
    //        return ret;
    //    }
    //
    //    res_data = as_calloc(data_length);
    //
    //    if(res_data == NULL)
    //    {
    //        vm_file_close(fh);
    //        ret = AS_MEMORY_NOT_ENOUGH;
    //        return ret;
    //    }
    //
    //    vm_file_read(fh, res_data, data_length, &len);
    //
    //    if((ASUINT)data_length != len)
    //    {
    //        as_free(res_data);
    //        vm_file_close(fh);
    //        ret = AS_INTERNAL_ERROR;
    //        return ret;
    //    }
    //
    //    vm_file_close(fh);
    //    image_p->canvas_hdlr = vm_graphic_load_image(res_data, data_length);
    //
    //    if(image_p->canvas_hdlr < VM_GDI_SUCCEED)
    //    {
    //        as_free(res_data);
    //        ret = AS_INTERNAL_ERROR;
    //        return ret;
    //    }
    //
    //#endif//AS_USE_IMAGE_RESOURCE_MANAGER
    //    //get width and height of the image
    //    prop_p = vm_graphic_get_img_property(image_p->canvas_hdlr, 1);
    //    image_p->img_w = prop_p->width;
    //    image_p->img_h = prop_p->height;
    //
    //    if(if_auto_resize == TRUE && (image_p->img_w > image_p->base.area.w || image_p->img_h > image_p->base.area.h))
    //    {
    //        //if the image is larger than the area , we will reload it with a smaller size
    //#ifdef AS_USE_IMAGE_RESOURCE_MANAGER
    //        img_resmgr_p->delete_canvas_for_reload(img_resmgr_p, image_p->canvas_hdlr);
    //        image_p->canvas_hdlr = img_resmgr_p->resize(img_resmgr_p, image_p->path, image_p->base.area.w, image_p->base.area.h);
    //
    //        if(image_p->canvas_hdlr < 0)
    //        {
    //            return AS_INTERNAL_ERROR;
    //        }
    //
    //#else
    //        vm_graphic_release_canvas(image_p->canvas_hdlr);
    //        image_p->canvas_hdlr = vm_graphic_load_image_resized(res_data, data_length, image_p->base.area.w, image_p->base.area.h);
    //
    //        if(image_p->canvas_hdlr < VM_GDI_SUCCEED)
    //        {
    //            as_free(res_data);
    //            ret = AS_INTERNAL_ERROR;
    //            return ret;
    //        }
    //
    //#endif
    //        prop_p = vm_graphic_get_img_property(image_p->canvas_hdlr, 1);
    //        image_p->img_w = prop_p->width;
    //        image_p->img_h = prop_p->height;
    //    }
    //
    //    if(res_data)
    //        as_free(res_data);
    //
    //    image_p->canvas_frames = vm_graphic_get_frame_number(image_p->canvas_hdlr);
    //    image_p->canvas_buf = vm_graphic_get_canvas_buffer(image_p->canvas_hdlr);
    return ret;
}

static as_ret as_ctrl_image_load_data_from_buffer(as_image* image_p, ASINT if_auto_resize)
{
    //struct frame_prop* prop_p = NULL;
    //AS_UNUSED(if_auto_resize);
    ///*make sure image_p->canvas_hdlr is valid*/
    //if(!image_p || image_p->canvas_hdlr < VM_GDI_SUCCEED)
    //{
    //    return AS_INVALID_PARAM;
    //}
    ////get width and height of the image
    //prop_p = vm_graphic_get_img_property(image_p->canvas_hdlr, 1);
    //image_p->img_w = prop_p->width;
    //image_p->img_h = prop_p->height;
    //image_p->canvas_frames = vm_graphic_get_frame_number(image_p->canvas_hdlr);
    //image_p->canvas_buf = vm_graphic_get_canvas_buffer(image_p->canvas_hdlr);
    return AS_OK;
}

static as_ret as_ctrl_image_load_data(as_control* ctrl_p, ASINT if_auto_resize)
{
    as_ret ret = AS_OK;
    as_image* image_p = NULL;

    if(!ctrl_p)
    {
        ret = AS_INVALID_PARAM;
        return ret;
    }

    image_p = (as_image*)ctrl_p;

    if(!image_p->path)
    {
        ret = AS_INVALID_PARAM;
        return ret;
    }

    if(image_p->src_type == AS_IMAGE_FROM_RES)
    {
        return as_ctrl_image_load_data_from_res(image_p, if_auto_resize);
    }
    //else if(image_p->src_type == AS_IMAGE_FROM_FILE)
    //{
    //    return as_ctrl_image_load_data_from_file(image_p, if_auto_resize);
    //}
    //else if(image_p->src_type == AS_IMAGE_FROM_BUFFER)
    //{
    //    return as_ctrl_image_load_data_from_buffer(image_p, if_auto_resize);
    //}
    else
    {
        return AS_INVALID_PARAM;
    }
}

static as_ret as_ctrl_image_unload_data(as_control* ctrl_p)
{
    as_ret ret = AS_OK;
    as_image* image_p = NULL;

    if(!ctrl_p)
    {
        ret = AS_INVALID_PARAM;
        return ret;
    }

    image_p = (as_image*) ctrl_p;

    if(image_p->src_type == AS_IMAGE_FROM_RES || image_p->src_type == AS_IMAGE_FROM_FILE)
    {
#ifdef AS_USE_IMAGE_RESOURCE_MANAGER
        as_image_resmgr*  img_resmgr_p = as_image_resmgr_get_instance();
        ret = img_resmgr_p->delete_by_path(img_resmgr_p, image_p->path);
#else//AS_USE_IMAGE_RESOURCE_MANAGER

        if(image_p->res_info.res_hdlr >= 0)
        {
            as_unload_res_internal(&image_p->res_info);
        }

#endif//AS_USE_IMAGE_RESOURCE_MANAGER
    }
    //else if(image_p->src_type == AS_IMAGE_FROM_BUFFER)
    //{
    //    if(image_p->canvas_hdlr)
    //    {
    //        //just reset canvas_hdlr to zero.
    //        image_p->canvas_hdlr = 0;
    //        image_p->canvas_buf = NULL;
    //    }
    //}
    else
    {
        return AS_INVALID_PARAM;
    }

    return ret;
}

static void as_ctrl_image_paint(as_control* ctrl_p)
{
    as_image* image_p = (as_image*)ctrl_p;
    ASINT layer;
    as_rect* rect_p = NULL;
    //ASINT frame_idx;
    as_rect area;
    ASUINT8* paint_buf;

    if(!ctrl_p || ctrl_p->if_hidden)
        return;

    rect_p = &image_p->base.area;
    as_memcpy(&area, rect_p, sizeof(as_rect));
    layer = ctrl_p->show_hdlr;

    if(layer < 0 || as_set_layer_clip_ex(layer, rect_p) == AS_IGNORE)
        return;

    paint_buf = as_get_layer_buffer_by_hdlr(layer);
    //if(image_p->canvas_frames == 1)
    //    frame_idx = 1;
    //else
    //    frame_idx = image_p->canvas_cur_frame_idx + 1;

    if(image_p->show_type &= AS_IMAGE_TILED)
    {
        area.y = rect_p->y;

        while(area.y < rect_p->y + rect_p->h)
        {
            area.x = rect_p->x;

            while(area.x < rect_p->x + rect_p->w)
            {
                if(image_p->if_trans)
                    as_draw_image_trans(paint_buf, area.x, area.y, &image_p->res_info);
                else
                    as_draw_image(paint_buf, area.x, area.y, &image_p->res_info);

                area.x += image_p->region.w;
            }

            area.y += image_p->region.h;
        }
    }
    else
    {
        if(image_p->show_type &= AS_IMAGE_LEFT_TOP)
        {
            area.x = rect_p->x;
            area.y = rect_p->y;
        }
        else if(image_p->show_type &= AS_IMAGE_CENTER)
        {
            area.x = rect_p->x + (rect_p->w - image_p->region.w) / 2;
            area.y = rect_p->y + (rect_p->h - image_p->region.h) / 2;
        }
        else //if(image_p->show_type == AS_IMAGE_CUSTOM)
        {
            area.x = rect_p->x + image_p->x_off;
            area.y = rect_p->y + image_p->y_off;
        }

        if(image_p->if_trans)
            as_draw_image_trans(paint_buf, area.x, area.y, &image_p->res_info);
        else
            as_draw_image(paint_buf, area.x, area.y, &image_p->res_info);
    }

    //as_reset_layer_clip(layer);
    //as_reset_clip();
}

static as_ret as_ctrl_image_set_region(as_control* ctrl_p, as_rect region)
{
    as_image* image_p = NULL;
    as_ret ret = AS_OK;

    if(!ctrl_p)
    {
        ret = AS_INVALID_PARAM;
        return ret;
    }

    image_p = (as_image*)ctrl_p;
    memcpy(&image_p->region, &region, sizeof(as_rect));
    return ret;
}

static as_ret as_ctrl_image_set_alpha(as_control* ctrl_p, ASINT alpha)
{
    as_image* image_p = NULL;
    as_ret ret = AS_OK;

    if(!ctrl_p)
    {
        ret = AS_INVALID_PARAM;
        return ret;
    }

    image_p = (as_image*)ctrl_p;

    if(alpha < 0)
        alpha = 0;

    if(alpha > 255)
        alpha = 255;

    image_p->alpha = alpha;
    return ret;
}

static as_ret as_ctrl_image_set_frame_idx(as_control* ctrl_p, ASINT idx)
{
    as_image* image_p = NULL;
    as_ret ret = AS_OK;

    if(!ctrl_p)
    {
        ret = AS_INVALID_PARAM;
        return ret;
    }

    image_p = (as_image*)ctrl_p;

    if(idx < 0)
        idx = 0;

    //if(idx >= image_p->canvas_frames)
    //{
    //    idx = image_p->canvas_frames - 1;
    //}
    //image_p->canvas_cur_frame_idx = idx;
    return ret;
}

static as_ret as_ctrl_image_set_show_type(as_control* ctrl_p, as_image_show_type show_type)
{
    as_image* image_p = (as_image*)ctrl_p;

    if(!image_p || show_type < AS_IMAGE_LEFT_TOP || show_type >= AS_IMAGE_SHOW_TYPE_MAX || image_p->show_type == show_type)
        return AS_INVALID_PARAM;

    image_p->show_type = show_type;
    return AS_OK;
}

static as_ret as_ctrl_image_set_if_trans(as_control* ctrl_p, ASINT if_trans)
{
    as_image* image_p = (as_image*)ctrl_p;

    if(!image_p || image_p->if_trans == if_trans)
        return AS_INVALID_PARAM;

    image_p->if_trans = if_trans;
    return AS_OK;
}

static as_ret as_ctrl_image_set_show_offset(as_control* ctrl_p, ASINT x_off, ASINT y_off)
{
    as_image* image_p = (as_image*)ctrl_p;

    if(!image_p || !(image_p->show_type & AS_IMAGE_CUSTOM))
        return AS_INVALID_PARAM;

    image_p->x_off = (ASINT16)x_off;
    image_p->y_off = (ASINT16)y_off;
    return AS_OK;
}

static void as_ctrl_image_set_hidden(as_control* ctrl_p, ASINT if_hidden)
{
    as_image* image_p = (as_image*)ctrl_p;

    if(!image_p)
        return;

    if(ctrl_p->if_hidden != if_hidden)
    {
        ctrl_p->if_hidden = if_hidden;

        if(if_hidden == TRUE)
        {
            image_p->unload_data(ctrl_p);
            //image_p->src_type = type;
            //image_p->canvas_hdlr = -1;
        }
        else
        {
            if(image_p->load_data((as_control*)image_p, ASFALSE/*image_p->if_auto_resize*/) != AS_OK)
            {
                as_log_fatal("<fatal error>~~~~~~when unhide,load image data failed~~~~~~~");
            }
        }
    }
}

as_image* as_ctrl_image_create(as_rect area,
                               as_image_src_type type, ASWSTR path, ASINT if_auto_resize)
{
    as_image* image_p = NULL;
    as_rect region;

    if(!path || type < AS_IMAGE_FROM_RES || type >= AS_IAMGE_SRC_TYPE_MAX)
    {
        return image_p;
    }

    image_p = as_calloc(sizeof(as_image));

    if(!image_p)
    {
        return image_p;
    }

    as_ctrl_init((as_control*)image_p, area);
    image_p->base.paint_hdlr = as_ctrl_image_paint;
    image_p->base.ctrl_type = AS_CTRL_IMAGE;
    image_p->base.set_hidden = as_ctrl_image_set_hidden;
    image_p->src_type = type;
    //image_p->canvas_hdlr = -1;

    if(image_p->src_type == AS_IMAGE_FROM_BUFFER)
    {
        //image_p->canvas_hdlr = (ASINT)path;
    }
    else
    {
        as_wstrcpy(image_p->path, path);
    }

    image_p->load_data = as_ctrl_image_load_data;
    image_p->unload_data = as_ctrl_image_unload_data;
    image_p->set_region = as_ctrl_image_set_region;
    image_p->set_alpha = as_ctrl_image_set_alpha;
    image_p->set_frame_idx = as_ctrl_image_set_frame_idx;
    image_p->set_show_type = as_ctrl_image_set_show_type;
    image_p->set_show_offset = as_ctrl_image_set_show_offset;
    image_p->set_if_trans = as_ctrl_image_set_if_trans;

    if(image_p->load_data((as_control*)image_p, if_auto_resize) != AS_OK)
    {
        as_log_fatal("[AS] <fatal error>  as_ctrl_image_create load_data error");
        as_free(image_p);
        image_p = NULL;
        return image_p;
    }

    image_p->show_type = AS_IMAGE_LEFT_TOP | AS_IMAGE_NORMAL;
    region.x = region.y = 0;
    region.w = image_p->img_w;
    region.h = image_p->img_h;
    image_p->set_region((as_control*)image_p, region);
    image_p->set_alpha((as_control*)image_p, 255);
    image_p->set_frame_idx((as_control*)image_p, 1);
    return image_p;
}

as_ret as_ctrl_image_destroy(as_image* ctrl_image_p)
{
    as_ret ret = AS_OK;

    if(!ctrl_image_p)
    {
        ret = AS_INVALID_PARAM;
        return ret;
    }

    ctrl_image_p->unload_data((as_control*)ctrl_image_p);
    as_free(ctrl_image_p);
    ctrl_image_p = NULL;
    return ret;
}